﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameEngine.Scenes;
using Microsoft.Xna.Framework;
using GameEngine.EntityComponents;
using GameEngine.Entities;
using Microsoft.Xna.Framework.Graphics;
using GameEngine.Managers.IManagers;
using PvT.Entities;
using GameEngine.Camera;
using System.Threading;

namespace PvT.Scenes
{
    public abstract class SceneWrapper : Scene
    {
        private Scene past;
        private Scene future;

        /// <summary>
        /// Initializes a new instance of the <see cref="SceneWrapper" /> class.
        /// </summary>
        /// <param name="game">The game.</param>
        public SceneWrapper(Game game) : base(game)
        {
        }


        /// <summary>
        /// Initializes a new instance of the <see cref="SceneWrapper" /> class.
        /// </summary>
        /// <param name="game">The game.</param>
        /// <param name="past">The past.</param>
        /// <param name="future">The future.</param>
        public SceneWrapper(Game game, Scene past, Scene future)
            : base(game)
        {
            this.past = past;
            this.future = future;
        }

        /// <summary>
        /// Pauses the action.
        /// </summary>
        public override void PauseAction()
        {
            if (past.isActive)
            {
                past.PauseAction();
            }
            else
            {
                future.PauseAction();
            }
        }

        /// <summary>
        /// Gets or sets the past.
        /// </summary>
        /// <value>
        /// The past.
        /// </value>
        public Scene Past
        {
            get
            {
                return past;
            }
            set
            {
                past = value;
            }
        }

        /// <summary>
        /// Gets or sets the future.
        /// </summary>
        /// <value>
        /// The future.
        /// </value>
        public Scene Future
        {
            get
            {
                return future;
            }
            set
            {
                future = value;
            }
        }

        /// <summary>
        /// Gets the scene objects.
        /// </summary>
        /// <returns></returns>
        public override List<AbstractEntity> GetSceneObjects()
        {
            if (past.isActive)
            {
                List<AbstractEntity> sceneObjects = new List<AbstractEntity>();
                foreach (Layer2D layer in past.Layers)
                {
                    sceneObjects.AddRange(layer.GetSceneObjects());
                }
                return sceneObjects;
            }
            else
            {
                List<AbstractEntity> sceneObjects = new List<AbstractEntity>();
                foreach (Layer2D layer in future.Layers)
                {
                    sceneObjects.AddRange(layer.GetSceneObjects());
                }
                return sceneObjects;
            }
        }


        /// <summary>
        /// Gets or sets the collision map.
        /// </summary>
        /// <value>
        /// The collision map.
        /// </value>
        public override Texture2D CollisionMap
        {
            get
            {
                if (past.isActive)
                {
                    return past.CollisionMap;
                }
                else
                {
                    return future.CollisionMap;
                }
            }
            set
            {
                if (past.isActive)
                {
                    future.CollisionMap = value;
                }
                else
                {
                    future.CollisionMap = value;
                }
            }
        }

        /// <summary>
        /// Gets or sets the death trap map.
        /// </summary>
        /// <value>
        /// The death trap map.
        /// </value>
        public override Texture2D DeathTrapMap
        {
            get
            {
                if (past.isActive)
                {
                    return past.DeathTrapMap;
                }
                else
                {
                    return future.DeathTrapMap;
                }
            }
            set
            {
                if (past.isActive)
                {
                    future.DeathTrapMap = value;
                }
                else
                {
                    future.DeathTrapMap = value;
                }
            }
        }

        /// <summary>
        /// Gets or sets the layers.
        /// </summary>
        /// <value>
        /// The layers.
        /// </value>
        public override List<Layer2D> Layers
        {
            get
            {
                if (past.isActive)
                {
                    return past.Layers;
                }
                else
                {
                    return future.Layers;
                }
            }
            set
            {
                if (past.isActive)
                {
                    past.Layers = value;
                }
                else
                {
                    future.Layers = value;
                }
            }
        }


        /// <summary>
        /// Updates the active Scene
        /// </summary>
        /// <param name="gameTime">The game time.</param>
        public override void Update(GameTime gameTime)
        {
            if (past.isActive)
            {
                
                if (scrollingBackground != null)
                    scrollingBackground.Update(1);
                List<AbstractEntity> entities = past.GetSceneObjects();
                foreach (AbstractEntity entity in entities)
                {
                    if (entity.GetType() == typeof(PlayerEntity))
                    {
                        if (!(((TerminateableComponent)entity.GetComponent(typeof(TerminateableComponent))).IsAlive()))
                        {
                            ISceneManager scene = (ISceneManager)game.Services.GetService(typeof(ISceneManager));
                            scene.PushScene(new GameOverScreen(game));
                        }
                    }
                    VortexComponent vortex = (VortexComponent)entity.GetComponent(typeof(VortexComponent));
                    if (vortex != null && vortex.TimeJump)
                    {
                        SwitchScene();
                        
                        //this.past.isActive = false;
                        //this.future.isActive = true;
                    }
                    entity.Update(gameTime);
                }

                CheckInput();
                
            }
            else if (future.isActive)
            {
                if (future.ScrollingBackground != null)
                    future.ScrollingBackground.Update(1);
                List<AbstractEntity> entities = future.GetSceneObjects();
                foreach (AbstractEntity entity in entities)
                {
                    if (entity.GetType() == typeof(PlayerEntity))
                    {
                        if (!(((TerminateableComponent)entity.GetComponent(typeof(TerminateableComponent))).IsAlive()))
                        {
                            ISceneManager scene = (ISceneManager)game.Services.GetService(typeof(ISceneManager));
                            scene.PushScene(new GameOverScreen(game));
                        }
                    }
                    VortexComponent vortex = (VortexComponent)entity.GetComponent(typeof(VortexComponent));
                    if (vortex != null && vortex.TimeJump)
                    {
                        SwitchScene();
                        //this.past.isActive = true;
                        //this.future.isActive = false;
                    }
                    entity.Update(gameTime);
                }

                CheckInput();
                
            }

        }

        /// <summary>
        /// Switches the scene.
        /// </summary>
        public void SwitchScene()
        {
            if (past.isActive)
            {
                past.isActive = false;
                future.isActive = true;
            }
            else
            {
                past.isActive = true;
                future.isActive = false;
            }
        }

        /// <summary>
        /// Draws the active Scene
        /// </summary>
        /// <param name="spriteBatch">The sprite batch.</param>
        /// <param name="gameTime">The game time.</param>
        public override void Draw(SpriteBatch spriteBatch, GameTime gameTime)
        {
            if (past.isActive)
            {
                past.Draw(spriteBatch, gameTime);
            }
            else
            {
                future.Draw(spriteBatch, gameTime);
            }
        }

    }
}
